package com.xinggq.pay.service.pay.faced;

import cn.hutool.core.lang.Validator;
import com.alibaba.fastjson2.JSONObject;
import com.xinggq.common.utils.TradeNoUtils;
import com.xinggq.pay.api.dto.YseCommonPayPespDTO;
import com.xinggq.pay.api.dto.YseCommonPayReqDTO;
import com.xinggq.pay.api.exception.PayException;
import com.xinggq.pay.service.context.AppIdContext;
import com.xinggq.pay.service.entity.PayOrderEntity;
import com.xinggq.pay.service.enums.PayChannelEnum;
import com.xinggq.pay.service.enums.TradeTypeEnum;
import com.xinggq.pay.service.pay.channel.PayChannelPayApiService;
import com.xinggq.pay.service.pay.channel.PayChannelResp;
import com.xinggq.pay.service.pay.channel.yse.enums.YsePayWayBindEnum;
import com.xinggq.pay.service.pay.channel.yse.utils.YseOutTradeNoUtil;
import com.xinggq.pay.service.service.PayOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;


/**
 * 银盛支付统一门面实现类
 * @Description
 * @Author xinggq
 * @Date 2025/9/15
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class YseFacedServiceImpl implements YseFacedService {

  private final PayOrderService payOrderService;

  @Override
  public <R> YseCommonPayPespDTO<R> pay(YseCommonPayReqDTO payReqDTO) {
    // 参数校验
    Validator.validateNotNull(payReqDTO, "支付请求参数不能为空");
    Validator.validateNotNull(payReqDTO.getYsePayWay(), "支付方式不能为空");
    if (StringUtils.isEmpty(payReqDTO.getChannelOutTradeNo())) {
      payReqDTO.setChannelOutTradeNo(YseOutTradeNoUtil.createTradeNo());
    }
    if (StringUtils.isEmpty(payReqDTO.getTradeNo())) {
      payReqDTO.setTradeNo(TradeNoUtils.generateTradeNo());
    }
    try {
      log.info("银盛统一支付开始，请求参数：{}", JSONObject.toJSONString(payReqDTO));
      
      // 保存支付订单记录
      savePayOrder(payReqDTO);
      
      return executePayment(payReqDTO);
    } catch (Exception e) {
      log.error("银盛统一支付异常", e);
      throw new PayException("支付处理异常", e);
    }
  }

  @SuppressWarnings("unchecked")
  private <R> YseCommonPayPespDTO<R> executePayment(YseCommonPayReqDTO payReqDTO) {
    PayChannelPayApiService<YseCommonPayReqDTO, PayChannelResp<R>> payService =
        (PayChannelPayApiService<YseCommonPayReqDTO, PayChannelResp<R>>) YsePayWayBindEnum.getServiceBeanByPayWay(
            payReqDTO.getYsePayWay());

    if (payService == null) {
      throw new PayException(String.format("不支持的支付方式：%s", payReqDTO.getYsePayWay()));
    }
    PayChannelResp<R> payResult = payService.pay(payReqDTO);
    return convertToCommonResponse(payReqDTO, payResult);
  }

  private <R> YseCommonPayPespDTO<R> convertToCommonResponse(YseCommonPayReqDTO payReqDTO,
      PayChannelResp<R> payResult) {

    YseCommonPayPespDTO<R> response = new YseCommonPayPespDTO<>();
    response.setMerchantOutTradeNo(payReqDTO.getMerchantOutTradeNo());
    response.setTradeNo(payReqDTO.getTradeNo());
    response.setPayData(payResult.getCommonResp());
    return response;


  }

  /**
   * 保存支付订单记录
   */
  private void savePayOrder(YseCommonPayReqDTO payReqDTO) {
    PayOrderEntity payOrder = new PayOrderEntity();
    payOrder.setAppId(AppIdContext.getAppId());
    payOrder.setTradeNo(payReqDTO.getTradeNo());
    payOrder.setMerchantOrderNo(payReqDTO.getMerchantOutTradeNo());
    payOrder.setChannelTradeNo(payReqDTO.getChannelOutTradeNo());
    payOrder.setChannelType(PayChannelEnum.YSE.getCode());
    payOrder.setPayWay(payReqDTO.getYsePayWay().getCode());
    payOrder.setTradeType(TradeTypeEnum.PAY.getCode());
    payOrder.setAmount(payReqDTO.getTotalAmount());
    payOrder.setSubject(payReqDTO.getSubject() != null ? payReqDTO.getSubject() : "银盛支付");

    payOrderService.save(payOrder);
    log.info("保存支付订单记录成功，订单号：{}", payReqDTO.getTradeNo());
  }
}
